home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 004 / gstobject / fasttimer / Example / usingAPCS < prev   
Text File  |  1994-09-17  |  4KB  |  116 lines

  1. ; example of writing assembler for use in APCS environment
  2.  
  3. ; in STM/LDM instructions rx..ry indicates any combinations
  4. ; (0 or more) of x..y may be present
  5.  
  6. ; x$stack_overflow and x$stack_overflow_1 are provided by
  7. ; the run time kernel
  8.  
  9. ;------------------------------------------------------------------------------------------------------
  10.  
  11. ; this next block identifies this routine
  12. ; should a backtrace be required
  13.  
  14.         =       "procedure name",0
  15.         ALIGN
  16.         &       &FF0000xx  ; xx is positive offset from this word back to start of string
  17. ; eg  "abcde",0 needs a value of &FF000008 (remember to include padding from ALIGN)
  18.  
  19. procedure
  20.         MOV     ip,sp
  21.         ; optional instruction to save arguments on entry
  22.         ; STMDB   sp!,{r0..r3}
  23.         STMDB   sp!,{r4..r9,fp,ip,lr,pc}
  24.         SUB     fp,ip,#4
  25.  
  26. ; only one of the following 3 peices of code should be used next
  27. ; depending on amount of stack used etc
  28.  
  29. ; (1) procedure will use no more than 512 bytes of stack and
  30. ;     will not call an external procedure
  31. ;     (internal routines can be considered as part of this one
  32. ;     provided they use a fixed amount of stack)
  33.  
  34.         ; no code required
  35.         ; guaranteed 512 bytes of space left on stack
  36.  
  37.  
  38. ; (2) procedure will use no more than 256 bytes of stack and
  39. ;     may call an external procedure
  40.  
  41.         CMP     sp,sl
  42.         BLLO    |x$stack_overflow|
  43.  
  44.  
  45. ; (3)  (a) procedure may use more than 512 bytes of stack
  46. ;          (and may or may not call external procedure)
  47. ;      OR
  48. ;      (b) procedure may use more than 256 bytes of stack and
  49. ;          may call external procedure
  50.  
  51.         SUB     ip,sp,#amount_of_stack_space_needed_in_bytes
  52.         CMP     ip,sl
  53.         BLLO    |x$_stack_overflow_1|
  54.         ; typical instruction to drop sp for local space
  55.         SUB     sp,sp,#amount_of_stack_space_needed_in_bytes
  56.         ; more code which uses local space,
  57.         ; always accessed using postive offsets from sp
  58.         ; eg STR r0,[sp,#positive_offset]
  59.  
  60.  
  61. ; main procedure body
  62. ; to access arguments which may have been pushed on stack
  63. ; also access with -ve offsets from fp
  64. ; eg LDR r0,[fp,#negative_offset]
  65.  
  66. ; remember to count stack use of internal subroutines
  67. ; as part of this procedure
  68.         BL      internal_subroutine
  69.  
  70. ; when calling an external procedure,
  71. ; sl,sp must be valid
  72.         BL      external_procedure
  73. ; on return:  r0-r3,ip,lr may be corrupted;   r4-r9,sl,fp are preserved
  74. ;             PSR flags are preserved
  75. ; (lr corrupted implies it may contain anything, not just the return
  76. ;  address setup by the BL)
  77.  
  78.         ; more code
  79.         ; must preserve sl,fp
  80.         ; may corrupt r0-r3,ip,lr
  81.         ; may corrupt r4..r9 but only if they are stacked at entry/exit
  82.  
  83.  
  84. ; when returning sl,fp must be valid
  85.  
  86.         MOV     r0,#return_value
  87. ; return with value in r0
  88.         LDMDB   fp,{r4..r9,fp,sp,pc}^
  89.  
  90.  
  91. ;------------------------------------------------------------------------------------------------------
  92.  
  93. EXTRA NOTES:
  94.  
  95. In leaf procedures (ones that call no other external procedures)
  96. various optimisations can be made to the entry/exit sequence.
  97.  
  98. eg
  99. procedure
  100.         LDR     r0,[r0,#Offset]
  101.         MOVS    pc,lr
  102.  
  103. It is important that a procedure always returns the flags using lr
  104. (usually stacked) and not the flags on entry. Consider the following
  105. example of a tail-optimised procedure calling an external procedure:
  106.  
  107. procedureA
  108.         CMP     r0,#value
  109.         MOVLO   r1,#constX
  110.         MOVHS   r1,#constY
  111.         B       procedureB
  112.  
  113. If procedureB was to restore the flags it saw on entry
  114. (not those in lr) then it will return to A's caller with the
  115. wrong flags.
  116.